﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 开机启动项设置工具
{
    public partial class Main : Form
    {
        #region Init
        private static RegistryKey LocalMachine = Registry.LocalMachine;
        private static RegistryKey CurrentUser = Registry.CurrentUser;
        private const string RunPath64 = @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run";
        private const string RunPath32 = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
        public Main()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 初始化加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Main_Load(object sender, EventArgs e)
        {
            dgv_grid.Columns.Add(new DataGridViewTextBoxColumn()
            {
                HeaderText = "注册表路径",
                Name = "BasePath",
                Visible = false
            });
            dgv_grid.Columns.Add("Name", "名称");
            dgv_grid.Columns.Add(new DataGridViewTextBoxColumn()
            {
                HeaderText = "数据",
                Name = "Value",
                AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
            });
            BindRegister();
        }
        #endregion
        #region register
        private void BindRegister()
        {
            dgv_grid.Rows.Clear();
            BindRegisterItem(LocalMachine, RunPath32);
            BindRegisterItem(LocalMachine, RunPath64);
            BindRegisterItem(CurrentUser, RunPath32);
            BindRegisterItem(CurrentUser, RunPath64);
        }

        private void BindRegisterItem(RegistryKey baseKey,string path)
        {
            var basePath = $@"{baseKey}\{path}"; 
            using RegistryKey runKey = baseKey.OpenSubKey(path);
            var names = runKey?.GetValueNames();
            if (names == null) return;
            foreach (var name in names)
            {
                var value = runKey.GetValue(name).ToString();
                dgv_grid.Rows.Add(basePath, name, value);
            }
        }
        #endregion
        #region 事件
        /// <summary>
        /// 选择要设置的开机程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txt_program_Click(object sender, EventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
            dialog.Filter = "应用程序(.exe)|*.exe|所有程序(*.*)|*.*";
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                txt_program.Text = dialog.FileName;
            }
        }
        /// <summary>
        /// add to regedit
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_add_Click(object sender, EventArgs e)
        {
            var program = txt_program.Text.Trim();
            AddRegister(program, false);
            BindRegister();
        }
        /// <summary>
        /// 移除启动项
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_remove_Click(object sender, EventArgs e)
        {
            if(dgv_grid.CurrentRow == null)
            {
                MessageBox.Show("请选择要移除的启动项！");
                return;
            }
            RemoveRegister(false);
            BindRegister();
        }
        /// <summary>
        /// gridview 行单机
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgv_grid_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            var value = dgv_grid.Rows[e.RowIndex].Cells["Value"].Value.ToString();
            var key = value.Split("\" ")[0];
            txt_program.Text = key.Trim().TrimStart('"').TrimEnd('"');
        }
        #endregion
        #region 提供给命令行的函数
        /// <summary>
        /// 添加注册
        /// </summary>
        /// <param name="program"></param>
        /// <param name="isConsole"></param>
        public void AddRegister(string program, bool isConsole)
        {
            if (!File.Exists(program))
            {
                if (!isConsole) MessageBox.Show("未找到程序！");
                Console.WriteLine("未找到程序!");
                return;
            }
            FileInfo file = new FileInfo(program);
            foreach(DataGridViewRow row in dgv_grid.Rows)
            {
                if (row.Cells["Name"].Value.Equals(file.Name.Substring(0,file.Name.LastIndexOf('.'))))
                {
                    if (!isConsole) MessageBox.Show("已存在该程序名！");
                    Console.WriteLine("已存在该程序名!");
                    return;
                }
            }
            using RegistryKey runKey = Registry.LocalMachine.CreateSubKey(RunPath64);
            runKey.SetValue(file.Name, program, RegistryValueKind.String);
        }
        /// <summary>
        /// 移除注册
        /// </summary>
        /// <param name="program"></param>
        /// <param name="isConsole"></param>
        public void RemoveRegister(bool isConsole)
        {
            var row = dgv_grid.CurrentRow;
            var fileName = row.Cells["Name"].Value.ToString();
            var basePath = row.Cells["BasePath"].Value.ToString();
            RegistryKey registry = null;
            switch (basePath.Substring(0, basePath.IndexOf('\\')))
            {
                case "HKEY_LOCAL_MACHINE":
                    registry = LocalMachine;break;
                case "HKEY_CURRENT_USER":
                    registry = CurrentUser;break;
            }
            if (registry == null) return;

            using RegistryKey runKey = registry.OpenSubKey(basePath.Substring(basePath.IndexOf('\\') + 1), true);
            var names = runKey?.GetValueNames();
            var list = names?.Where(name => runKey.GetValue(name).ToString().Contains(fileName));
            if (list.Count() == 0)
            {
                if (!isConsole) MessageBox.Show("没有找到对应的启动项！");
                Console.WriteLine("没有找到对应的启动项!");
                return;
            }
            if (list.Count() > 1)
            {
                if (!isConsole) MessageBox.Show("找到启动项大于1项，请手工处理！");
                Console.WriteLine("找到启动项大于1项，请手工处理!");
                return;
            }
            runKey.DeleteValue(list.First());
        }
        #endregion
    }
}
